///	<summary>
///	  Unit testing for libraries in DAttributes unit
///	</summary>
///	<remarks>
///	  Uses DUnit testing framework
///	</remarks>
unit DAttributes.Test;

(*******************************************************************************
  MIT License

  Copyright (c) 2013 - Luthfi Harahap

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:

  The above copyright notice and this permission notice shall be included in
  all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  THE SOFTWARE
*******************************************************************************)

interface

uses
  Windows
  , SysUtils
  , Classes
  , Variants
  , TestFramework
  , DAttributes
  ;

const
  PUBLIC_INT_PROPERTY_NAME = 'PublicIntProperty';
  PUBLIC_INT_PROPERTY_DEFAULTVALUE = 456;
  PUBLIC_INT_PROPERTY_TESTVALUE = 88354;

  PUBLIC_BYTE_PROPERTY_NAME = 'PublicByteProperty';
  PUBLIC_BYTE_PROPERTY_DEFAULTVALUE = 123;
  PUBLIC_BYTE_PROPERTY_TESTVALUE = 92;

  PUBLIC_STRING_PROPERTY_NAME = 'PublicStringProperty';
  PUBLIC_STRING_PROPERTY_DEFAULTVALUE = 'WSTRING';
  PUBLIC_STRING_PROPERTY_TESTVALUE = 'QWERTY';

  PUBLIC_EXTENDED_PROPERTY_NAME = 'PublicExtendedProperty';
  PUBLIC_EXTENDED_PROPERTY_DEFAULTVALUE = 45030312.3529323;
  PUBLIC_EXTENDED_PROPERTY_TESTVALUE = 814734.5532884;

type
  ///	<summary>
  ///	  Dummy class for testing custom attributes
  ///	</summary>
  TDefaultValueAttrTestClass=class
  private
    FPublicStringProperty: string;
    FPublicIntProperty: Integer;
    FPublicExtendedProperty: Extended;
    FPublicByteProperty: Integer;
  public
    constructor Create;

    [DefaultValue(PUBLIC_INT_PROPERTY_DEFAULTVALUE)]
    property PublicIntProperty: Integer read FPublicIntProperty write FPublicIntProperty;
    [DefaultValue(PUBLIC_BYTE_PROPERTY_DEFAULTVALUE)]
    property PublicByteProperty: Integer read FPublicByteProperty write FPublicByteProperty;
    [DefaultValue(PUBLIC_STRING_PROPERTY_DEFAULTVALUE)]
    property PublicStringProperty: string read FPublicStringProperty write FPublicStringProperty;
    [DefaultValue(PUBLIC_EXTENDED_PROPERTY_DEFAULTVALUE)]
    property PublicExtendedProperty: Extended read FPublicExtendedProperty write FPublicExtendedProperty;
  end;

  ///	<summary>
  ///	  Unit tests for IniSection attribute class
  ///	</summary>
  TDefaultValueTest=class(TTestCase)
  protected
    class function TestedDefaultValueClass: DefaultValueClass; virtual;
  published
    procedure Test_Create;
    procedure Test_ResetObject;
  end;

implementation


{TDefaultValueTest}

class function TDefaultValueTest.TestedDefaultValueClass: DefaultValueClass;
begin
  Result := DefaultValue;
end;

procedure TDefaultValueTest.Test_Create;
var
  vDefValue: DefaultValue;
  vByteValue: Byte;
  vInt64Value: Int64;
  vExtendedValue: TDateTime;
begin
  Randomize;
  RandSeed := GetTickCount;
  vInt64Value := Random(MaxInt);
  vByteValue := Random(MaxByte);
  vExtendedValue := Time;

  // check string default value
  vDefValue := Self.TestedDefaultValueClass.Create(PUBLIC_STRING_PROPERTY_DEFAULTVALUE);
  try
    Check(VarCompareValue(PUBLIC_STRING_PROPERTY_DEFAULTVALUE, vDefValue.DefValue)=vrEqual);
    Check(vDefValue.DefValue=PUBLIC_STRING_PROPERTY_DEFAULTVALUE);
  finally
    vDefValue.Free;
  end;

  // Check int64 value
  vDefValue := Self.TestedDefaultValueClass.Create(vInt64Value);
  try
    Check(VarCompareValue(vInt64Value, vDefValue.DefValue)=vrEqual);
    Check(vDefValue.DefValue=vInt64Value);
  finally
    vDefValue.Free;
  end;

  // Test byte value
  vDefValue := Self.TestedDefaultValueClass.Create(vByteValue);
  try
    Check(VarCompareValue(vByteValue, vDefValue.DefValue)=vrEqual);
    Check(vDefValue.DefValue=vByteValue);
  finally
    vDefValue.Free;
  end;

  // Test float value
  vDefValue := Self.TestedDefaultValueClass.Create(vExtendedValue);
  try
    Check(VarCompareValue(vExtendedValue, vDefValue.DefValue)=vrEqual);
    Check(vDefValue.DefValue=vExtendedValue);
  finally
    vDefValue.Free;
  end;
end;

procedure TDefaultValueTest.Test_ResetObject;
var
  O: TDefaultValueAttrTestClass;
begin
  O := TDefaultValueAttrTestClass.Create;
  try
    O.PublicIntProperty := PUBLIC_INT_PROPERTY_TESTVALUE;
    O.PublicByteProperty := PUBLIC_BYTE_PROPERTY_TESTVALUE;
    O.PublicStringProperty := PUBLIC_STRING_PROPERTY_TESTVALUE;
    O.PublicExtendedProperty := PUBLIC_EXTENDED_PROPERTY_TESTVALUE;

    // make sure all properies do no have their default values
    Check(O.PublicIntProperty <> PUBLIC_INT_PROPERTY_DEFAULTVALUE);
    Check(O.PublicByteProperty <> PUBLIC_BYTE_PROPERTY_DEFAULTVALUE);
    Check(O.PublicStringProperty <> PUBLIC_STRING_PROPERTY_DEFAULTVALUE);
    Check(O.PublicExtendedProperty <> PUBLIC_EXTENDED_PROPERTY_DEFAULTVALUE);

    // reset the test object
    DAttributes.Reset(O);

    // Check that all properties got their default values back
    Check(O.PublicIntProperty = PUBLIC_INT_PROPERTY_DEFAULTVALUE);
    Check(O.PublicByteProperty = PUBLIC_BYTE_PROPERTY_DEFAULTVALUE);
    Check(O.PublicStringProperty = PUBLIC_STRING_PROPERTY_DEFAULTVALUE);
    Check(CompareFloats(O.PublicExtendedProperty, PUBLIC_EXTENDED_PROPERTY_DEFAULTVALUE)=0);
  finally
    O.Free;
  end;
end;

{ TDefaultValueAttrTestClass }

constructor TDefaultValueAttrTestClass.Create;
begin
//  DAttributes.Reset(Self);
end;

initialization
  TestFramework.RegisterTest('', TDefaultValueTest.Suite);
end.
